/*
 *  Copyright 2012 Dirk Vranckaert
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package eu.vranckaert.vvl.utils.view;

import android.util.Log;
import android.widget.LinearLayout;
import eu.vranckaert.vvl.R;
import eu.vranckaert.vvl.activities.DashboardActivity;
import eu.vranckaert.vvl.activities.test.MyActivityTestCase;
import eu.vranckaert.vvl.testutil.TestConstants;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * User: DIRK VRANCKAERT
 * Date: 24/02/12
 * Time: 14:38
 */
public class MultiSelectSpinnerTest extends MyActivityTestCase<DashboardActivity> {
    private static final String LOG_TAG = MultiSelectSpinnerTest.class.getSimpleName();

    private String[] items = {"item1", "item2", "item3", "item4"};
    private List<Boolean> selectedValues = new ArrayList<Boolean>();
    private String allSelected = "Everything is selected";
    private String noneSelected = "";
    private String title = "Window title";

    public MultiSelectSpinnerTest() {
        super(DashboardActivity.class);
    }

    private MultiSelectSpinner createMultiSelectSpinner(Boolean[] defaultValues) {
        final LinearLayout container = (LinearLayout) getActivity().findViewById(R.id.home_root);

        final MultiSelectSpinner multiSelectSpinner = new MultiSelectSpinner(getActivity());
        multiSelectSpinner.setItems(
                Arrays.asList(items),
                Arrays.asList(defaultValues),
                allSelected,
                noneSelected,
                title,
                new MultiSelectSpinner.MultiSelectSpinnerListener() {
                    @Override
                    public void onItemsSelected(boolean[] selected) {
                        selectedValues.clear();
                        for (boolean s : selected) {
                            selectedValues.add(s);
                        }
                    }
                }
        );
        try {
            runTestOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.i(LOG_TAG, "Removing all views from the activity");
                    container.removeAllViews();
                    Log.i(LOG_TAG, "Adding the multi select spinner to the activity");
                    container.addView(multiSelectSpinner);
                }
            });
        } catch (Throwable throwable) {}

        return multiSelectSpinner;
    }

    public void testDeviceBackButton() {
        Boolean[] defaultValues = {false, false, false, false};
        MultiSelectSpinner multiSelectSpinner = createMultiSelectSpinner(defaultValues);

        assertEquals("", noneSelected, (String) multiSelectSpinner.getSelectedItem());
        solo.clickOnView(multiSelectSpinner);
        solo.clickOnMenuItem(items[2]);
        solo.goBack();
        Log.i(LOG_TAG, "Waiting 10 seconds for UI to be updated!");
        solo.waitForDialogToClose(TestConstants.Time.FIVE_SECONDS);
        assertEquals("", noneSelected, (String) multiSelectSpinner.getSelectedItem());
    }

    public void testNegative() {
        Boolean[] defaultValues = {false, false, false, false};
        MultiSelectSpinner multiSelectSpinner = createMultiSelectSpinner(defaultValues);

        assertEquals("", noneSelected, (String) multiSelectSpinner.getSelectedItem());
        solo.clickOnView(multiSelectSpinner);
        solo.clickOnMenuItem(items[2]);
        solo.clickOnButton(getActivity().getString(R.string.cancel));
        Log.i(LOG_TAG, "Waiting 10 seconds for UI to be updated!");
        solo.waitForDialogToClose(TestConstants.Time.FIVE_SECONDS);
        assertEquals("", noneSelected, (String) multiSelectSpinner.getSelectedItem());
    }

    public void testPositive() {
        Boolean[] defaultValues = {false, false, false, false};
        MultiSelectSpinner multiSelectSpinner = createMultiSelectSpinner(defaultValues);

        assertEquals("", noneSelected, (String) multiSelectSpinner.getSelectedItem());
        solo.clickOnView(multiSelectSpinner);
        solo.clickOnMenuItem(items[2]);
        solo.clickOnButton(getActivity().getString(R.string.ok));
        Log.i(LOG_TAG, "Waiting 10 seconds for UI to be updated!");
        solo.waitForDialogToClose(TestConstants.Time.FIVE_SECONDS);
        assertEquals("", items[2], (String) multiSelectSpinner.getSelectedItem());
    }

    public void testSelectOneItem() {
        Boolean[] defaultValues = {false, false, false, false};
        MultiSelectSpinner multiSelectSpinner = createMultiSelectSpinner(defaultValues);

        assertEquals("", noneSelected, (String) multiSelectSpinner.getSelectedItem());
        solo.clickOnView(multiSelectSpinner);
        solo.clickOnMenuItem(items[2]);
        solo.clickOnButton(getActivity().getString(R.string.ok));
        Log.i(LOG_TAG, "Waiting 10 seconds for UI to be updated!");
        solo.waitForDialogToClose(TestConstants.Time.FIVE_SECONDS);
        assertEquals("", items[2], (String) multiSelectSpinner.getSelectedItem());
    }

    public void testSelectMoreItems() {
        Boolean[] defaultValues = {false, false, false, false};
        MultiSelectSpinner multiSelectSpinner = createMultiSelectSpinner(defaultValues);

        assertEquals("", noneSelected, (String) multiSelectSpinner.getSelectedItem());
        solo.clickOnView(multiSelectSpinner);
        solo.clickOnMenuItem(items[2]);
        solo.clickOnMenuItem(items[1]);
        solo.clickOnMenuItem(items[3]);
        solo.clickOnButton(getActivity().getString(R.string.ok));
        Log.i(LOG_TAG, "Waiting 10 seconds for UI to be updated!");
        solo.waitForDialogToClose(TestConstants.Time.FIVE_SECONDS);
        String expectedResult = items[1] + ", " + items[2] + ", " + items[3];
        assertEquals("", expectedResult, (String) multiSelectSpinner.getSelectedItem());
    }

    public void testSelectAllItems() {
        Boolean[] defaultValues = {false, false, false, false};
        MultiSelectSpinner multiSelectSpinner = createMultiSelectSpinner(defaultValues);

        assertEquals("", noneSelected, (String) multiSelectSpinner.getSelectedItem());
        solo.clickOnView(multiSelectSpinner);
        solo.clickOnMenuItem(items[2]);
        solo.clickOnMenuItem(items[0]);
        solo.clickOnMenuItem(items[1]);
        solo.clickOnMenuItem(items[3]);
        solo.clickOnButton(getActivity().getString(R.string.ok));
        Log.i(LOG_TAG, "Waiting 10 seconds for UI to be updated!");
        solo.waitForDialogToClose(TestConstants.Time.FIVE_SECONDS);
        assertEquals("", allSelected, (String) multiSelectSpinner.getSelectedItem());
    }

    public void testSelectNoItems() {
        String oldNoneSelected = noneSelected;
        noneSelected = "Nothing is selected!";

        Boolean[] defaultValues = {false, false, false, false};
        MultiSelectSpinner multiSelectSpinner = createMultiSelectSpinner(defaultValues);

        assertEquals("", noneSelected, (String) multiSelectSpinner.getSelectedItem());
        noneSelected = oldNoneSelected;
    }

    public void testWithoutDefaultValues() {
        Boolean[] defaultValues = {false, false, false, false};
        MultiSelectSpinner multiSelectSpinner = createMultiSelectSpinner(defaultValues);

        assertEquals("", noneSelected, (String) multiSelectSpinner.getSelectedItem());
        solo.clickOnView(multiSelectSpinner);
        solo.clickOnMenuItem(items[2]);
        solo.clickOnButton(getActivity().getString(R.string.ok));
        Log.i(LOG_TAG, "Waiting 10 seconds for UI to be updated!");
        solo.waitForDialogToClose(TestConstants.Time.FIVE_SECONDS);
        assertEquals("", items[2], (String) multiSelectSpinner.getSelectedItem());
    }

    public void testWithOneDefaultValue() {
        Boolean[] defaultValues = {false, true, false, false};
        MultiSelectSpinner multiSelectSpinner = createMultiSelectSpinner(defaultValues);

        String expectedResultBefore = items[1];
        assertEquals("", expectedResultBefore, (String) multiSelectSpinner.getSelectedItem());
        solo.clickOnView(multiSelectSpinner);
        solo.clickOnMenuItem(items[2]);
        solo.clickOnMenuItem(items[0]);
        solo.clickOnMenuItem(items[1]);
        solo.clickOnMenuItem(items[3]);
        solo.clickOnButton(getActivity().getString(R.string.ok));
        Log.i(LOG_TAG, "Waiting 10 seconds for UI to be updated!");
        solo.waitForDialogToClose(TestConstants.Time.FIVE_SECONDS);
        String expectedResultAfter = items[0] + ", " + items[2] + ", " + items[3];
        assertEquals("", expectedResultAfter, (String) multiSelectSpinner.getSelectedItem());
    }

    public void testWithMultipleDefaultValue() {
        Boolean[] defaultValues = {false, true, false, true};
        MultiSelectSpinner multiSelectSpinner = createMultiSelectSpinner(defaultValues);

        String expectedResultBefore = items[1] + ", " + items[3];
        assertEquals("", expectedResultBefore, (String) multiSelectSpinner.getSelectedItem());
        solo.clickOnView(multiSelectSpinner);
        solo.clickOnMenuItem(items[2]);
        solo.clickOnButton(getActivity().getString(R.string.ok));
        Log.i(LOG_TAG, "Waiting 10 seconds for UI to be updated!");
        solo.waitForDialogToClose(TestConstants.Time.FIVE_SECONDS);
        String expectedResultAfter = items[1] + ", " + items[2] + ", " + items[3];
        assertEquals("", expectedResultAfter, (String) multiSelectSpinner.getSelectedItem());
    }
}
